package io.adrainty.bolee.security.repository.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.adrainty.bolee.security.mapper.IRoleDeptMapper;
import io.adrainty.bolee.security.mapper.IRoleMapper;
import io.adrainty.bolee.security.mapper.IRoleResourceMapper;
import io.adrainty.bolee.security.models.bo.RoleBO;
import io.adrainty.bolee.security.models.bo.RoleDeptBO;
import io.adrainty.bolee.security.models.bo.RoleResourceBO;
import io.adrainty.bolee.security.models.entity.RoleEntity;
import io.adrainty.bolee.security.repository.IRoleRepository;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author AdRainty
 * @version V1.0.0
 * @since 2025/8/9 下午11:21
 */

@Repository
public class RoleRepositoryImpl implements IRoleRepository {

    @Resource
    private IRoleMapper roleMapper;

    @Resource
    private IRoleDeptMapper roleDeptMapper;

    @Resource
    private IRoleResourceMapper roleResourceMapper;

    @Override
    public List<RoleEntity> findRoleByUserId(List<Long> userId) {
        return roleMapper.findRoleByUserId(userId);
    }

    @Override
    public IPage<RoleEntity> findRolePage(RoleEntity entity, Integer pageNum, Integer pageSize) {
        Wrapper<RoleBO> wrapper = getWrapper(entity);
        Page<RoleBO> page = new Page<>(pageNum, pageSize);
        return roleMapper.selectPage(page, wrapper)
                .convert(item -> BeanUtil.copyProperties(item, RoleEntity.class));
    }

    @Override
    public List<RoleEntity> listRole(RoleEntity entity) {
        Wrapper<RoleBO> wrapper = getWrapper(entity);
        List<RoleBO> selectedList = roleMapper.selectList(wrapper);
        return BeanUtil.copyToList(selectedList, RoleEntity.class);
    }

    @Override
    public boolean saveRole(RoleEntity entity) {
        RoleBO roleBO = BeanUtil.copyProperties(entity, RoleBO.class);
        boolean result = roleMapper.insert(roleBO) > 0;
        if (!result) return false;
        BeanUtil.copyProperties(roleBO, entity);
        return true;
    }

    @Override
    public boolean updateRole(RoleEntity entity) {
        RoleBO roleBO = BeanUtil.copyProperties(entity, RoleBO.class);
        return roleMapper.updateById(roleBO) > 0;
    }

    @Override
    public List<RoleDeptBO> findRoleDeptByRoleIds(List<Long> roleIdList) {
        if (CollUtil.isEmpty(roleIdList)) return List.of();
        Wrapper<RoleDeptBO> wrapper = Wrappers.lambdaQuery(RoleDeptBO.class)
                .in(RoleDeptBO::getRoleId, roleIdList);
        return roleDeptMapper.selectList(wrapper);
    }

    @Override
    public Map<String, List<RoleEntity>> findRoleListByResourceNo(List<String> resourceNoList) {
        List<Map<String, Object>> roleBOList = roleMapper.findRoleListByResourceNo(resourceNoList);

        Map<String, List<RoleEntity>> groupedMap = new HashMap<>();
        for (Map<String, Object> item : roleBOList) {
            String resourceNo = (String) item.get("key");
            RoleEntity roleBO = (RoleEntity) item.get("value");
            List<RoleEntity> roleEntities = groupedMap.getOrDefault(resourceNo, new ArrayList<>());
            roleEntities.add(roleBO);
            groupedMap.put(resourceNo, roleEntities);
        }
        return groupedMap;
    }

    @Override
    public void saveBatchRoleResource(List<RoleResourceBO> roleResourceList) {
        roleResourceMapper.insert(roleResourceList);
    }

    @Override
    public void saveBatchRoleDept(List<RoleDeptBO> roleDeptList) {
        roleDeptMapper.insert(roleDeptList);
    }

    @Override
    public void deleteRoleDeptByRoleId(Long id) {
        Wrapper<RoleDeptBO> wrapper = Wrappers.lambdaQuery(RoleDeptBO.class)
                .eq(RoleDeptBO::getRoleId, id);
        roleDeptMapper.delete(wrapper);
    }

    @Override
    public void deleteRoleResourceByRoleId(Long id) {
        Wrapper<RoleResourceBO> wrapper = Wrappers.lambdaQuery(RoleResourceBO.class)
                .eq(RoleResourceBO::getRoleId, id);
        roleResourceMapper.delete(wrapper);
    }

    private Wrapper<RoleBO> getWrapper(RoleEntity entity) {
        return Wrappers.lambdaQuery(RoleBO.class)
                .eq(StringUtils.isNotBlank(entity.getCompanyNo()), RoleBO::getCompanyNo, entity.getCompanyNo())
                .eq(entity.getDataState() != null, RoleBO::getDataState,entity.getDataState())
                .likeRight(StringUtils.isNotBlank(entity.getRoleName()), RoleBO::getRoleName, entity.getRoleName())
                .likeRight(StringUtils.isNotBlank(entity.getLabel()), RoleBO::getLabel, entity.getLabel())
                .orderByAsc(RoleBO::getSortNo);
    }
}
